#include <iostream>
#include <future>
#include <memory>
#include <thread>

// packaged_task的学习使用
// packaged_task是一个模板类，实例化的对象可以对一个函数进行二次封装
// 可以通过get_future得到future对象，获取封装的函数的异步执行结果

int Add(int num1, int num2)
{
    return num1 + num2;
}

int main()
{
    std::packaged_task<int(int, int)> task(Add);
    // task(11, 22); // task可以当作可调用对象来执行，但又不能完全当成函数使用
    // std::async(std::launch::async, task, 11, 22); // 编译报错，模板参数不匹配，因为task不能完全当成函数使用
    // std::thread(task, 11, 22) // 理由同上
    // 但我们可以把task定义为指针，传递到线程中，解引用执行
    // 为了防止出现变量的生命周期问题，我们可以在堆上new该对象，用智能指针进行管理
    auto ptask = std::make_shared<std::packaged_task<int(int, int)>>(Add);
    std::future<int> fut = ptask->get_future();
    std::thread thr([ptask](){
        (*ptask)(11, 22);
    });
    int sum = fut.get();
    std::cout << sum << std::endl;
    thr.join();
    return 0;
}